# makina language lexer+parser to use with packcc parser generator https://github.com/clnhlzmn/makina
%prefix "makina"

%source{

#include <stdio.h>

static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };

#define PCC_DEBUG(event, rule, level, pos, buffer, length) \
    fprintf(stdout, "%*s%s %s @%d [%.*s]\n", (int)(level * 2), "", dbg_str[event], rule, (int)pos, (int)length,  buffer); fflush(stdout)

    /* NOTE: To guarantee the output order, stderr, which can lead a race condition with stdout, is not used. */

}

file <- _ 'machine' _ ID _ ';' _ state* _ !.


state <- statehead?  statebody*

statehead <-
	 'initial'
	/ 'final'

statebody	<-	_ statehead? _ 'state' _ id _ '{' _ statebody* _ '}' _
	/ handler

id <-	['.']? _ ID _ (['.'] ID)*

handler <-	'entry' _ action _ ';' _
	/ 'exit' _ action _ ';' _
	/ 'on' _ ID _ guard? _ action? _ target? _ ';' _


action <-	ID _

guard <-	'(' _ ID _ ')'


target <-	'->' _ id
    / '-->' _ id

ID  <- [a-zA-Z_]+[a-zA-Z_0-9]*
    / '`' !('`')+ .* '`'


WHITESPACE <-	(' '/'\t'/'\u000C'/'\n'/'\r')

COMMENT <-	"//" (!endofline .)*

_	<- (WHITESPACE / COMMENT /endofline)*

endofline	<-	( '\r\n' / '\n' / '\r' / '\n\r' )


%%

int main() {
    makina_context_t *ctx=makina_create(NULL);
    while (makina_parse(ctx, NULL)){;}
    makina_destroy(ctx);
    return 0;
}

